<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <title>Apple App 50B CounterDown Forcast</title>
        <link rel="stylesheet" type="text/css" media="screen" href="css/examples.css" />
		<link rel="stylesheet" type="text/css" media="screen" href="css/jquery-ui.min.css" />
        <script type="text/javascript" src="js/jquery.min.js"></script>        
		<script type="text/javascript" src="js/jquery-ui.min.js"></script>
        <script type="text/javascript" src="js/jquery.flot.min.js"></script>       
		<script type="text/javascript" src="js/jquery.flot.navigate.min.js"></script>
		<script type="text/javascript" src="js/jquery.flot.resize.min.js"></script> 
		<script type="text/javascript" src="js/sylvester.js"></script>
		

	</head>
    <body>
		

		<div id="content">
		
		<div class="header">	<h1>Apple App 50B CounterDown Forcast</h1>	</div>
		<p><a href="http://www.apple.com/itunes/50-billion-app-countdown/">http://www.apple.com/itunes/50-billion-app-countdown/</a></p>
		<p id="forcast"> </p>
		<p id="forcast2"> </p>
		<p id="forcast3"> </p>

		<div class="demo-container">
        <div id="placeholder" class="demo-placeholder" ></div>
		</div>

		</div>

		  <script type="text/javascript">

		   //get lineear function  y = ax + b
			function getLinear(xylist,nCount)
			{	
				if(nCount==null ){
					nCount = xylist.length;
				}
				else if(nCount >= xylist.length)
				{
					nCount = xylist.length;
				}

				var xbase = xylist[0][0];
				var ybase = xylist[0][1];

				var sumx = 0;
				var sumx2 = 0;
				var sumy = 0;
				var sumxy = 0;
				for(var i=xylist.length-nCount;i<xylist.length;i++)
				{
					var x = xylist[i][0] - xbase;
					var y = xylist[i][1] - ybase;
					sumx += x;
					sumx2 += x*x;
					sumy += y;
					sumxy += x * y;
				}
				//var nCount = xylist.length;
				//y = ax + b
				var b = (sumx2*sumy -sumx*sumxy)/(nCount*sumx2 -sumx*sumx);
				var a = (nCount*sumxy - sumx*sumy)/(nCount*sumx2 - sumx*sumx);
				b += (ybase-a*xbase);

				return {a:a,b:b};
			}

			//get quadratic function y = ax^2 + bx + c
			function getQuadratic(xylist,nCount)
			{
				if(nCount==null ){
					nCount = xylist.length;
				}
				else if(nCount >= xylist.length)
				{
					nCount = xylist.length;
				}
				var xbase = xylist[0][0];
				var ybase = xylist[0][1];

				var sumx = 0;
				var sumx2 = 0;
				var sumx3 = 0;
				var sumx4 = 0;
				var sumy = 0;
				var sumxy = 0;
				var sumx2y = 0;
				for(var i=xylist.length-nCount;i<xylist.length;i++)
				{
					var x = xylist[i][0] - xbase;
					var y = xylist[i][1] - ybase;
					sumx += x;
					sumx2 += x*x;
					sumx3 += x*x*x;
					sumx4 += x*x*x*x;
					sumy += y;
					sumxy += x * y;
					sumx2y+= x*x*y;
				}		
				var M = $M([
					[nCount, sumx, sumx2],
					[sumx,sumx2,sumx3],
					[sumx2,sumx3,sumx4]
				]);
				var V = $V([sumy,sumxy,sumx2y]);
				var invM = M.inverse();
				var ret = invM.multiply(V);
				var a = ret.e(3);
				var b = ret.e(2);
				var c = ret.e(1);
				var fixb = -2*a*xbase + b;
				var fixc = a*xbase*xbase-b*xbase+c+ybase;
				return {a:a, b: fixb, c:fixc };
			}
			//cubic function  y=ax^3 + bx^2 + cx + d 
			function getCubic(xylist,nCount)
			{
				if(nCount==null ){
					nCount = xylist.length;
				}
				else if(nCount >= xylist.length)
				{
					nCount = xylist.length;
				}
				var xbase = xylist[0][0];
				var ybase = xylist[0][1];

				var sumx = 0;
				var sumx2 = 0;
				var sumx3 = 0;
				var sumx4 = 0;
				var sumx5 = 0;
				var sumx6 = 0;
				var sumy = 0;
				var sumxy = 0;
				var sumx2y = 0;
				var sumx3y = 0;
				
				for(var i=xylist.length-nCount;i<xylist.length;i++)
				{
					var x = xylist[i][0] - xbase;
					var y = xylist[i][1] - ybase;
					sumx += x;
					sumx2 += x*x;
					sumx3 += x*x*x;
					sumx4 += x*x*x*x;
					sumx5 += x*x*x*x*x;
					sumx6 += x*x*x*x*x*x;
					sumy += y;
					sumxy += x * y;
					sumx2y+= x*x*y;
					sumx3y+= x*x*x*y;
				}		
				
				var M = $M([
					[nCount, sumx, sumx2,sumx3],
					[sumx,sumx2,sumx3,sumx4],
					[sumx2,sumx3,sumx4,sumx5],
					[sumx3,sumx4,sumx5,sumx6]
				]);
				var V = $V([sumy,sumxy,sumx2y,sumx3y]);
				var invM = M.inverse();
				var ret = invM.multiply(V);
				var a = ret.e(4);
				var b = ret.e(3);
				var c = ret.e(2);
				var d = ret.e(1);
				var fixb = b - 3*a*xbase;
				var fixc = 3*a*xbase*xbase - 2*b*xbase +c;
				var fixd = -a*xbase*xbase*xbase +b*xbase*xbase - c*xbase + d + ybase;
				return {a:a,b:fixb,c:fixc,d:fixd};
				
			}
			//show tooltips 
			function showTooltip(x, y, contents) {
				$('<div id="tooltip">' + contents + '</div>').css( {
					 position: 'absolute',
					 display: 'none',
					 top: y + 5,
					left: x + 5,
					border: '1px solid #fdd',
					padding: '2px',
					'background-color': '#fee',
					 opacity: 0.80
				}).appendTo("body").fadeIn(200);
			}
			//var SCALE = 1;
			//
            $(function() {
				//get data
				var datasource = 'http://www.favorrank.com:3000';
				$.getScript(datasource, function(){

					var fcount = 49300000000;
					var tcount = 50000000000;
					var time = (new Date()).getTime()/1000;
					//var timeline = [[fcount,time],[tcount,time]];
					//var timeline = [[time,fcount],[time,tcount]];
				
					
					var dataline = [];
					for(var i=0;i<data.alldata.length;i++)
					{
						//draw time line						
						var item = data.alldata[i];
						//x.push([i,1]);
						dataline.push([item.count, item.sampleTimestamp]);						
					}

					var line = getLinear(dataline);
					var line2 = getQuadratic(dataline);
					var line3 = getCubic(dataline);
					
					var tTime = tcount*line.a+line.b;
					var tTime2 = 0;
					var myline = [[fcount,fcount*line.a + line.b],[tcount,tTime]];	
					var myline2 = [];
					var myline3 = [];
					for(var i = 0.0;i<=1;i+=0.1)
					{
						var icount = fcount*i+tcount*(1-i);
						var itime2 = line2.a*icount*icount + line2.b*icount+line2.c;
						var itime3 = line3.a*icount*icount*icount + line3.b*icount*icount + line3.c*icount + line3.d;
						myline2.push([icount,itime2]);
						myline3.push([icount,itime3]);
					}
					tTime2 = line2.a*tcount*tcount + line2.b*tcount+line2.c;
					var tTime3 = line3.a*tcount*tcount*tcount + line3.b*tcount*tcount + line3.c*tcount + line3.d;
					
					
					var forcast = new Date();
					forcast.setTime(tTime*1000);
					$("#forcast").html("Forcast: " + forcast.toLocaleString());
					forcast.setTime(tTime2*1000);
					$("#forcast2").html("Forcast2: " + forcast.toLocaleString());
					forcast.setTime(tTime3*1000);
					$("#forcast3").html("Forcast3: " + forcast.toLocaleString());
			
					var option = { 
						series:{ lines:{show:true}, points:{show:true} },
						grid: { hoverable: true, clickable: true },
						//xaxis:{ panRange: [fcount, tcount] },
						//yaxis: { panRange: [fcount, tcount] },
						zoom:{ interactive:true },
						pan:{ interactive:true}
					};
				
					var l_data = {data:dataline, label:"Samples" };
					//var l_time = {data:timeline, label:"Current Time" };
					var l_myline = {data:myline, label:"Forcast Line" };
					var l_myline2 = {data:myline2, label:"Forcast Line 2" };
					var l_myline3 = { data:myline3, label:"Forcast Line 3" };

					$.plot("#placeholder",[l_data,l_myline,l_myline2,l_myline3],option);	
				});  

				//add tooltip function
				var previousPoint = null;
				$("#placeholder").bind("plothover", function (event, pos, item) {
					 //$("#x").text(pos.x.toFixed(2));
					// $("#y").text(pos.y.toFixed(2));     
					 if (item) {
						if (previousPoint != item.dataIndex) {
							previousPoint = item.dataIndex;							
							$("#tooltip").remove();
							var x = item.datapoint[0].toFixed(2),
								y = item.datapoint[1].toFixed(2);
							var ytime = new Date();
							ytime.setTime(y*1000);
							
							showTooltip(item.pageX, item.pageY,
										 ytime.toLocaleString()  );
						}
					 }
					 else {
						$("#tooltip").remove();
						previousPoint = null;            
					 }
				 });
				
				//
				$(".demo-container").resizable({
						maxWidth: 1650,
						maxHeight: 1200,
						minWidth: 450,
						minHeight: 250,
				});
				
				

            });

			
        </script>
    </body>
</html>
